package com.qingzhuge.common.utils;

import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;


import javax.servlet.http.HttpServletRequest;
import java.io.File;
import java.net.InetAddress;
import java.net.NetworkInterface;
import java.net.UnknownHostException;
import java.util.Enumeration;

/**
 * @author : zero.xiao
 * @description : IP地址
 * @date :2018/6/14 0014 下午 17:30
 * @since : 1.0.0
 * @modified :
 */
@Slf4j
public class IpUtils {
    private static final String UNKNOWN = "unknown";
    private static final String LOCALHOST_IP4 = "127.0.0.1";
    private static final String LOCALHOST_IP6 = "0:0:0:0:0:0:0:1";
    private static final String COMMA = ",";
    private static final Integer IP_LENGTH = 15;

	/**
	 * 获取IP地址
	 * 
	 * 使用Nginx等反向代理软件， 则不能通过request.getRemoteAddr()获取IP地址
	 * 如果使用了多级反向代理的话，X-Forwarded-For的值并不止一个，而是一串IP地址，X-Forwarded-For中第一个非unknown的有效IP字符串，则为真实IP地址
	 */
	public static String getIpAddr(HttpServletRequest request) {
    	String ip = null;
        try {
            ip = request.getHeader("x-forwarded-for");
            if (StringUtils.isEmpty(ip) || UNKNOWN.equalsIgnoreCase(ip)) {
                ip = request.getHeader("Proxy-Client-IP");
            }
            if (StringUtils.isEmpty(ip) || ip.length() == 0 || UNKNOWN.equalsIgnoreCase(ip)) {
                ip = request.getHeader("WL-Proxy-Client-IP");
            }
            if (StringUtils.isEmpty(ip) || UNKNOWN.equalsIgnoreCase(ip)) {
                ip = request.getHeader("HTTP_CLIENT_IP");
            }
            if (StringUtils.isEmpty(ip) || UNKNOWN.equalsIgnoreCase(ip)) {
                ip = request.getHeader("HTTP_X_FORWARDED_FOR");
            }
            if (StringUtils.isBlank(ip) || UNKNOWN.equalsIgnoreCase(ip)) {
                ip = request.getHeader("X-Real-IP");
            }

            if (StringUtils.isEmpty(ip) || UNKNOWN.equalsIgnoreCase(ip)) {
                ip = request.getRemoteAddr();
                if (LOCALHOST_IP4.equals(ip) || LOCALHOST_IP6.equals(ip)) {
                    // 根据网卡取本机配置的IP
                    ip = getLocalIP();
                }
            }

            if (ip != null && ip.indexOf(COMMA) > 0) {
                // 对于通过多个代理的情况，第一个IP为客户端真实IP,多个IP按照','分割
                String[] ips = ip.split(COMMA);
                for (String ip2 : ips) {
                    if (!UNKNOWN.equalsIgnoreCase(ip2)) {
                        ip = ip2;
                        break;
                    }
                }
            }

            // 对于通过多个代理的情况，第一个IP为客户端真实IP,多个IP按照','分割
//            if (ip != null && ip.length() > IP_LENGTH) {
//                if (ip.indexOf(COMMA) > 0) {
//                    ip = ip.substring(0, ip.indexOf(COMMA));
//                }
//            }
        } catch (Exception e) {
        	log.error("IPUtils ERROR ", e);
        }
        
        return ip;
    }
    /**
     * 取当前系统站点本地地址 linux下 和 window下可用
     * @return
     */
    private static String getLocalIP() {
        String sIP = "";
        InetAddress ip = null;
        try {
            // 如果是Windows操作系统
            if (isWindowsOS()) {
                ip = InetAddress.getLocalHost();
            }
            // 如果是Linux操作系统
            else {
                boolean bFindIP = false;
                Enumeration<NetworkInterface> netInterfaces = NetworkInterface.getNetworkInterfaces();
                while (netInterfaces.hasMoreElements()) {
                    if (bFindIP) {
                        break;
                    }
                    NetworkInterface ni = netInterfaces.nextElement();
                    // ----------特定情况，可以考虑用ni.getName判断
                    // 遍历所有ip
                    Enumeration<InetAddress> ips = ni.getInetAddresses();
                    while (ips.hasMoreElements()) {
                        ip = ips.nextElement();
                        // 127.开头的都是lookback地址
                        if (ip.isSiteLocalAddress() && !ip.isLoopbackAddress()
                                && !ip.getHostAddress().contains(":")) {
                            bFindIP = true;
                            break;
                        }
                    }
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        if (null != ip) {
            sIP = ip.getHostAddress();
        }
        return sIP;
    }

    /**
     * 判断当前系统是否是Windows操作系统
     */
    private static boolean isWindowsOS() {
        return "//".equals(File.separator);
    }

    /** 获取机器名 */
    public static String getHostName() {
        String hostName = "";
        try {
            hostName = InetAddress.getLocalHost().getHostName();
        } catch (UnknownHostException e) {
            log.error(e.getMessage(), e);
        }
        return hostName;
    }
}
